﻿using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MemoLib.Tasks
{
    /// <summary>
    /// 周期性任务
    /// </summary>
    public class CycleTask : Task
    {
        /// <summary>
        /// 根据频度来判断下次执行时间
        /// </summary>
        /// <param name="taskCard"></param>
        /// <returns></returns>
        private DateTime GetNextExecuteTime(CycleTaskCard taskCard)
        {
            DateTime ret = DateTime.Now;
            DateTime tempDateTime = DateTime.Now;
            int quantity = taskCard.Quantity.Value;

            int interval = int.Parse(ConfigOperator.GetIntervalMinutes().ToString()) + 5;
            switch (taskCard.Frequency)
            {
                case FrequencyType.Month:
                    tempDateTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, taskCard.Day.Value, taskCard.Hour.Value, taskCard.Minute.Value, 0);
                    // 如果指定的日期和时间是晚于当前日期时间，那么将发生在当月
                    if((tempDateTime - DateTime.Now).TotalMinutes >= interval)
                    {
                        ret = tempDateTime;
                    }
                    // 如果是早于当前的日期时间，那么将发生在下个月
                    else
                    {   
                        ret = tempDateTime.AddMonths(quantity);
                    }
                    break;
                case FrequencyType.Week:
                    int offset = 0; // 日期偏移量
                    // 星期日
                    if (DateTime.Now.DayOfWeek == 0)
                    {
                        offset = taskCard.Weekday.Value - 7;
                    }
                    else
                    {
                        offset = taskCard.Weekday.Value -(int)DateTime.Now.DayOfWeek;
                    }

                    tempDateTime = DateTime.Now.AddDays(offset);
                    tempDateTime = new DateTime(tempDateTime.Year, tempDateTime.Month, tempDateTime.Day, taskCard.Hour.Value, taskCard.Minute.Value, 0);
                    // 如果临时时间晚于当前时间，那么临时时间就是下次执行时间
                    if ((tempDateTime - DateTime.Now).TotalMinutes >= interval)
                    {
                        ret = tempDateTime;
                    }
                    else
                    {
                        ret = tempDateTime.AddDays(7 * quantity);
                    }
                    break;
                case FrequencyType.Day:
                    tempDateTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, taskCard.Hour.Value, taskCard.Minute.Value, 0);
                    if ((tempDateTime - DateTime.Now).TotalMinutes >= interval)
                    {
                        ret = tempDateTime;
                    }
                    else
                    {
                        ret = tempDateTime.AddDays(quantity);
                    }
                    break;
                case FrequencyType.Hour:
                    ret = DateTime.Now.AddHours(quantity);
                    break;
            }

            return ret;
        }

        /// <summary>
        /// 获取下次执行时间，更新对应字段
        /// </summary>
        /// <param name="eop"></param>
        public override void UpdateTaskStatus(ExcelOperator eop)
        {
            CycleTaskCard taskCard = this.Card as CycleTaskCard;

            DateTime nextExeTime = DateTime.Now;
            if (taskCard != null)
            {
                eop.UpdateCellValue(CommonData.CYCLETASK_SHEETNAME, CommonData.LASTEXECUTEDATETIME, Utility.GetDateTimeString(this.Card.ExecuteDateTime), this.Card.CardID.ToString());
                nextExeTime = this.GetNextExecuteTime(taskCard);
                eop.UpdateCellValue(CommonData.CYCLETASK_SHEETNAME, CommonData.CYCLETASK_NEXT, Utility.GetDateTimeString(nextExeTime), this.Card.CardID.ToString());
            }
        }

        public void WriteNextExecuteTime(ExcelOperator eop)
        {
            this.UpdateTaskStatus(eop);
        }
        public bool IsOverdue()
        {
            CycleTaskCard taskCard = this.Card as CycleTaskCard;
            bool ret = false;
            int quantity = taskCard.Quantity.Value;
            switch (taskCard.Frequency)
            {
                case FrequencyType.Month:
                    ret = DateTime.Now.AddMonths(-1 * quantity) > taskCard.ExecuteDateTime;
                    break;
                case FrequencyType.Week:
                    ret = DateTime.Now.AddDays(-7 * quantity) > taskCard.ExecuteDateTime;
                    break;
                case FrequencyType.Day:
                    ret = DateTime.Now.AddDays(-quantity) > taskCard.ExecuteDateTime;
                    break;
                case FrequencyType.Hour:
                    ret = DateTime.Now.AddHours(-quantity) > taskCard.ExecuteDateTime;
                    break;
            }

            ExcelOperator eop = new ExcelOperator(ConfigOperator.GetExcelPath());
            // 更新工卡状态信息
            eop.OpenConn();
            UpdateTaskStatus(eop);
            eop.CloseConn();
            return ret;
        }

        /// <summary>
        /// 判断当前任务的下次执行时间是否在本次之间范围内，依据是执行时间
        /// </summary>
        /// <returns></returns>
        public bool IsTooEarly()
        {
            CycleTaskCard taskCard = this.Card as CycleTaskCard;
            return (taskCard.ExecuteDateTime - DateTime.Now).TotalMinutes > ConfigOperator.GetIntervalMinutes();
        }
    }
}
